CpFlag=[0,0,0]
knownCps =[]
runOnce = 0
initialLoc =()
enemyInitialLoc =()

class Agent(object):

    NAME = "Shoot_My_Ass" # Replay filenames and console output will contain this name.
    
    #defined on Monday
    flagCp = 0;

    def __init__(self, id, team, settings=None, field_rects=None, field_grid=None, nav_mesh=None):
       
        self.id = id
        self.team = team
        self.mesh = nav_mesh
        self.grid = field_grid
        self.settings = settings
        self.goal = None
        pass



    def observe(self, observation):
        self.observation = observation
        self.selected = observation.selected       

    def action(self):
            global initialLoc
            global runOnce
            global enemyInitialLoc
         #if self.id==0 :#or self.id==1 or self.id==2:
            obs = self.observation
            
            if runOnce==0:
                initialLoc = obs.loc
                enemyInitialLoc = (initialLoc[0]+576,initialLoc[1])
                print "red---initial Loc : "+str(self.id)+" "+str(initialLoc)
                runOnce=1
            
            
            # agent obatin 3 main goals
            obtainCPList = self.computeCPDist()
            obtainAmmoList = self.computAmmaDist()
            obtainEnemyList = self.computEnemyDist()
            
            #print obs.foes
            #print obtainEnemyList
            
            agentLoc = obs.loc;
            
                      
            # 1.I see CP and Ammo and Enemy at the same time
            if obtainCPList !=[] and obtainAmmoList !=[] and obtainEnemyList !=[]:
                #print "# 1.I see CP and Ammo and Enemy at the same time"
                # calculate 4 distances
                distCp=abs(agentLoc[0] - obtainCPList[0][0])+abs(agentLoc[1] - obtainCPList[0][1])+0.00001 
                distAmmo=abs(agentLoc[0] - obtainAmmoList[0][0])+abs(agentLoc[1] - obtainAmmoList[0][1])+0.00001 
                distEnemy2Cp = abs(obtainEnemyList[0][0] - obtainCPList[0][0])+abs(obtainEnemyList[0][1] - obtainCPList[0][1])+0.00001 
                distEnemy2Ammo = abs(obtainEnemyList[0][0] - obtainAmmoList[0][0])+abs(obtainEnemyList[0][1] - obtainAmmoList[0][1])+0.00001 
                # I have no ammo, grab first
                if obs.ammo ==0:
                    if distCp < distEnemy2Cp and distAmmo > distEnemy2Ammo:
                        self.goal = obtainCPList[0]
                    if distCp > distEnemy2Cp and distAmmo < distEnemy2Ammo:
                        self.goal = obtainAmmoList[0]
                    if distCp < distEnemy2Cp and distAmmo < distEnemy2Ammo:
                        self.goal = obtainAmmoList[0]
                    if distCp > distEnemy2Cp and distAmmo > distEnemy2Ammo:
                        if distEnemy2Cp < distEnemy2Ammo:
                            self.goal = obtainAmmoList[0]
                        else :
                            self.goal = obtainCPList[0]
                # I have ammo, attack first
                elif obs.ammo >0:
                    if distEnemy2Cp < distEnemy2Ammo:
                        if(distCp/distEnemy2Cp)<(1.0/2):
                            self.goal = obtainCPList[0]
                        else:
                            self.goal = obtainEnemyList[0][0:2]
                    else: 
                        if(distAmmo/distEnemy2Ammo)<(1.0/2):
                            self.goal = obtainAmmoList[0]
                        else:
                            self.goal = obtainEnemyList[0][0:2]
                            
            # 2.I see CP and Ammo at the same time
            if obtainCPList !=[] and obtainAmmoList !=[] and obtainEnemyList ==[]:
                 #print "# 2.I see CP and Ammo at the same time"
                 # calculate 2 distances
                 distCp=abs(agentLoc[0] - obtainCPList[0][0])+abs(agentLoc[1] - obtainCPList[0][1]) +0.00001 
                 distAmmo=abs(agentLoc[0] - obtainAmmoList[0][0])+abs(agentLoc[1] - obtainAmmoList[0][1]) +0.00001 
                 # I have no ammo, grab first
                 if obs.ammo ==0:
                     self.goal = obtainAmmoList[0]
                 elif obs.ammo >0 and obs.ammo<=3:
                     if (distAmmo/distCp)<(1.0/2):
                         self.goal = obtainAmmoList[0]
                     else:
                         self.goal = obtainCPList[0]
                 elif obs.ammo >3:
                     self.goal = obtainCPList[0]
            
            # 3.I see Cp and Enemy at the same time
            if obtainCPList !=[] and obtainEnemyList !=[] and obtainAmmoList ==[] :
                #print "# 3.I see Cp and Enemy at the same time"
                # calculate 2 distances
                distCp = abs(agentLoc[0] - obtainCPList[0][0])+abs(agentLoc[1] - obtainCPList[0][1]) +0.00001 
                distEnemy2Cp = abs(obtainEnemyList[0][0] - obtainCPList[0][0])+abs(obtainEnemyList[0][1] - obtainCPList[0][1])+0.00001 
                # I have no ammo, rush to Cp
                if obs.ammo ==0:
                    self.goal = obtainCPList[0]
                # I have ammo, consider attack first
                else:
                    if(distCp/distEnemy2Cp)<(1.0/2):
                        self.goal = obtainCPList[0]
                    else:
                        self.goal = obtainEnemyList[0][0:2]
            
            # 4.I see Ammo and Enemy at the same time
            if obtainEnemyList !=[] and obtainAmmoList !=[] and obtainCPList ==[] :
                #print "# 4.I see Ammo and Enemy at the same time"
                # calculate 2 distances
                distAmmo=abs(agentLoc[0] - obtainAmmoList[0][0])+abs(agentLoc[1] - obtainAmmoList[0][1])+0.00001 
                distEnemy2Ammo = abs(obtainEnemyList[0][0] - obtainAmmoList[0][0])+abs(obtainEnemyList[0][1] - obtainAmmoList[0][1])+0.00001 
                # I have no ammo, grab first
                if obs.ammo==0:
                    self.goal = obtainAmmoList[0]
                else:
                    if(distAmmo/distEnemy2Ammo)<(1.0/2):
                        self.goal = obtainAmmoList[0]
                    else:
                        self.goal = obtainEnemyList[0][0:2]
            
            # 5.I only see Cp
            if obtainCPList !=[] and obtainAmmoList ==[] and obtainEnemyList ==[] :
                #print "# 5.I only see Cp"
                self.goal = obtainCPList[0]
            # 6.I only see ammo
            if obtainAmmoList !=[] and obtainCPList ==[] and obtainEnemyList ==[] :
                #print "# 6.I only see ammo"
                self.goal = obtainAmmoList[0]
            # 7.I only see enemy
            if obtainEnemyList !=[] and obtainAmmoList ==[] and obtainCPList==[] :
                #print "# 7.I only see enemy"
                self.goal = obtainEnemyList[0][0:2]
            # 8.I see nothing
            if obtainCPList ==[] and obtainAmmoList ==[] and obtainEnemyList ==[] :
                #print "# 8.I see nothing"
                self.goal = None
            
            
                
            
            
            #if self.goal is not None and point_dist(self.goal, obs.loc) < self.settings.tilesize:
                #self.goal = None
                
            
            # Walk to random CP
            if self.goal is None:
                    self.goal = obs.cps[random.randint(0,len(obs.cps)-1)][0:2]
                
            
#            if obs.ammo > 0 and obtainEnemyList :
#                print "I found the enemy"+str(obtainEnemyList)
#                self.goal = obtainEnemyList
            
            # Shoot enemies
            shoot = False
            if (obs.ammo > 0 and 
                obs.foes and 
                point_dist(obtainEnemyList[0][0:2], obs.loc) < self.settings.max_range
                and not line_intersects_grid(obs.loc, obtainEnemyList[0][0:2], self.grid, self.settings.tilesize)):
                self.goal = obtainEnemyList[0][0:2]
                #print "I am going to shoot :"+str(self.goal)        
                shoot = True        
            
                
            # Compute path, angle and drive
            path = find_path(obs.loc, self.goal, self.mesh, self.grid, self.settings.tilesize)
            if path:
                dx = path[0][0]-obs.loc[0]
                dy = path[0][1]-obs.loc[1]
                turn = angle_fix(math.atan2(dy, dx)-obs.angle)
                if turn > self.settings.max_turn or turn < -self.settings.max_turn:
                    shoot = False
                speed = (dx**2 + dy**2)**0.5
            else:
                turn = 0
                speed = 0
            
            #print "**************my goal is :"+str(self.goal)+" turn:"+str(turn)+" shoot:"+str(shoot)
            return (turn,speed,shoot)
         #return (0, 0, False)

    def debug(self, surface):
        import pygame
        # First agent clears the screen
        if self.id == 0:
            surface.fill((0,0,0,0))
        # Selected agents draw their info
        if self.selected:
            if self.goal is not None:
                pygame.draw.line(surface,(0,0,0),self.observation.loc, self.goal)

    def finalize(self, interrupted=False):
        pass
    
    def computeCPDist(self):
        global knownCps
        
        obs = self.observation
        unknownCps = [obs.cps[0][0:3] , obs.cps[1][0:3], obs.cps[2][0:3]]
        knownCps =[]
        for cp in unknownCps:
            if self.team ==0:
                if cp[2]!=0:
                    knownCps.append(cp)
            if self.team ==1:
                if cp[2]!=1:
                    knownCps.append(cp)
        
        
        if knownCps !=[]:
            #print len(knownCps)
            agentLoc = obs.loc
            cpsDist = [( abs(agentLoc[0] - cp[0])  + abs(agentLoc[1] - cp[1]) ) for cp in knownCps]
            #print cpsDist
            minIndex = cpsDist.index(min(cpsDist))
            targetCP = [knownCps[minIndex][0:2]]
            #knownCps.pop(minIndex)
            #print "length = "+str(len(knownCps))
            return targetCP
            #add new for Cooperation
            
#            if len(knownCps)==1:
#                return targetCP
#            if len(knownCps)==2:
#                if self.id ==0 or self.id ==1 or self.id ==2:
#                    return targetCP
#                if self.id ==3 or self.id ==4 or self.id ==5:
#                    targetCP2 = [knownCps[1-minIndex][0:2]]
#                    return targetCP2
#            if len(knownCps)==3:
#                print knownCps
#                print cpsDist
#                maxIndex = cpsDist.index(max(cpsDist))
#                if self.id ==0 or self.id ==1:
#                    #print str(self.id)+"Three CP--group1"
#                    return targetCP
#                if self.id ==2 or self.id ==3:
#                    targetCP2 = [knownCps[maxIndex][0:2]]
#                    #print str(self.id)+"Three CP--group2"
#                    return targetCP2
#                if self.id ==4 or self.id ==5:
#                    targetCP3 = [knownCps[3-maxIndex-minIndex][0:2]]
#                    #print str(self.id)+"Three CP--group3"
#                    return targetCP3
        else:
            return []

    
    def computAmmaDist(self):
        obs = self.observation
        agentLoc = obs.loc
        ammopacks = filter(lambda x: x[2] == "Ammo", obs.objects)
        if ammopacks:
             ammoDist = [( abs(agentLoc[0] - ammo[0])  + abs(agentLoc[1] - ammo[1]) ) for ammo in ammopacks]
             minIndex = ammoDist.index(min(ammoDist))
             targetAmmo = [ammopacks[minIndex][0:2]]
             return targetAmmo
        else:
             return []

    def computEnemyDist(self):
        obs = self.observation
        agentLoc = obs.loc
        enemypacks = obs.foes
        #print "enemy = "+ str(enemypacks)
        if enemypacks!=[]:
            #enemyDist =  [( abs(agentLoc[0] - enemy[0])  + abs(agentLoc[1] - enemy[1]) ) for enemy in enemypacks]
            #minIndex = enemyDist.index(min(enemyDist))
            enemyAngle = [abs(enemy[2]) for enemy in enemypacks]
            minIndex = enemyAngle.index(min(enemyAngle))
            targetEnemy = [enemypacks[minIndex][0:3]]
            return targetEnemy
        else:
            return []
